package com.mdp.tpa.wechat.service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import com.mdp.tpa.wechat.HttpRequestUtil;
import com.mdp.tpa.wechat.wxpaysdk.MyWxPayConfig;
import com.mdp.tpa.wechat.wxpaysdk.WXPay;
import com.mdp.tpa.wechat.wxpaysdk.WXPayConfig;
import com.mdp.tpa.wechat.wxpaysdk.WXPayUtil;
import com.mdp.tpa.wechat.api.ApiUrls;
import com.mdp.tpa.wechat.api.PayService;
import com.mdp.tpa.wechat.api.SignService;
import com.mdp.tpa.wechat.util.RandomUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mdp.core.entity.Tips;
import com.mdp.core.err.BizException;
import com.mdp.core.utils.DateUtils;
import org.springframework.util.StringUtils;

@Service
public class PayServiceImpl implements PayService {
	
	Log log=LogFactory.getLog(PayServiceImpl.class);

	@Autowired
    SignService wxApiSign;
	
	String unifiedOrderXml= ""
			+ "<xml> "
				+ "<appid>%s</appid>  "
				+ "<attach>%s</attach>  "
				+ "<body>%s</body>  "
				+ "<mch_id>%s</mch_id> "
				+ "<nonce_str>%s</nonce_str>  "
				+ "<notify_url>%s</notify_url> "
				+ "<openid>%s</openid> "
				+ "<out_trade_no>%s</out_trade_no>"
				+ "<spbill_create_ip>%s</spbill_create_ip> "
				+ "<total_fee>%s</total_fee>"
				+ "<fee_type>%s</fee_type>"
				+ "<trade_type>%s</trade_type> "
				+ "<sign>%s</sign> "
			+ "</xml>";
	
	 
	@Override
	public Map<String, Object> unifiedOrder(WXPayConfig config, String outTradeNo, String body, String attach,
			String spbillCreateIp, Integer totalFee,String goodsTag, String openid) {
		Map<String,Object> m=new HashMap<String,Object>();
		Date d=new Date();
		String timestamp=(d.getTime()+"").substring(3);
	    String nonceStr= RandomUtil.getRandomStr();
	    Map<String,Object> p=new HashMap<>(); 
		String tradeType="JSAPI";
		String mchId=config.getMchId();
		String notifyUrl= config.getNotifyUrl();
		String payKey=config.getKey();
	    String feeType="CNY";
	    String profitSharing = "Y";
	    //p.put("goods_tag", goodsTag);
		p.put("appid", config.getAppId());
		p.put("mch_id",mchId);
		p.put("nonce_str", nonceStr);
		p.put("openid", openid);
		p.put("body", body);
		p.put("out_trade_no", outTradeNo);
		p.put("fee_type", feeType);
		p.put("total_fee", totalFee);
		p.put("notify_url", notifyUrl);
		p.put("trade_type", tradeType);
		p.put("spbill_create_ip", spbillCreateIp);
		p.put("attach", attach);
//		p.put("profit_sharing", profitSharing);
		String sign=wxApiSign.signPayMd5(p, payKey);
		p.put("sign", sign.toUpperCase());
		String xml=String.format(unifiedOrderXml, config.getAppId(),attach,body,mchId,nonceStr,notifyUrl,openid,outTradeNo,spbillCreateIp,totalFee,feeType,tradeType,sign.toUpperCase());
		Map<String,Object> orderMap= HttpRequestUtil.sendPostXml(ApiUrls.PAY_UNIFIEDORDER, xml);
		    if(orderMap.containsKey("return_code") && orderMap.containsKey("result_code")){
		    	if("SUCCESS".equalsIgnoreCase((String) orderMap.get("result_code"))){
		    		String prepayid=(String) orderMap.get("prepay_id"); 
		    		m.put("appId", p.get("appid"));
		    		m.put("timeStamp", timestamp);
		    		m.put("nonceStr", (String) orderMap.get("nonce_str"));
		    		m.put("package", "prepay_id="+prepayid);
		    		m.put("signType", "MD5");
		    		String sign2=wxApiSign.signPayMd5(m,  payKey);
		    		m.put("paySign", sign2.toUpperCase());
		    		m.put("prepay_id", orderMap.get("prepay_id"));
		    	}else{
		    		throw new BizException((String) orderMap.get("err_code"), (String) orderMap.get("err_code_des"));
		    	}
		    }else{
		    	/**
		    	return_code><![CDATA[FAIL]]></return_code>
		    	<return_msg><![CDATA[body参数长度有误]]></return_msg>
		    	</xml>
		    	**/
		    	String errMsg= (String) orderMap.get("return_msg");
		    	throw new BizException("WxPayServie105",errMsg==null?"向微信申请支付出错":errMsg);
		    }
			 
			return m; 
	}


	@Override
	public Map<String, Object> orderQuery(WXPayConfig config, String outTradeNo) {
	    String nonceStr=RandomUtil.getRandomStr();
	    Map<String,String> p=new HashMap<>();
		p.put("appid", config.getAppId());
		p.put("mch_id",config.getMchId());
		p.put("nonce_str", nonceStr);
		p.put("out_trade_no", outTradeNo);  


	        WXPay wxpay = new WXPay(config);
	       try {
			Map<String,String> resp= wxpay.orderQuery(p);
			 Map<String, Object> respMap=new HashMap<>();
		        respMap.putAll(resp);
		        return respMap;
		} catch (Exception e) {
			 log.error("",e);
			 throw new BizException(e.getMessage());
		} 
	       
	}

	/**
	 * 退费成功返回的结果
	 * {transaction_id=4200000304201903259563106349, nonce_str=RJ1SDresltcnyc3S, out_refund_no=test002, sign=2B989CDF8C657F91C735DC6E0A7594FC, return_msg=OK, mch_id=1499315292, refund_id=50000510022019032508891122009, cash_fee=30, out_trade_no=2xjaz4h314, coupon_refund_fee=0, refund_channel=, appid=wxf57f8625a9f88554, refund_fee=30, total_fee=30, result_code=SUCCESS, coupon_refund_count=0, cash_refund_fee=30, return_code=SUCCESS}
	 */
	@Override
	public Map<String, Object> refund(WXPayConfig config, String outTradeNo, String outRefundNo,Integer totalFee, Integer refundFee) {

   
        WXPay wxpay = new WXPay(config);

        Map<String, String> data = new HashMap<String, String>();
        data.put("out_trade_no", outTradeNo);
        data.put("out_refund_no", outRefundNo);
        //data.put("total_fee", refundFee.toString());
        data.put("total_fee", totalFee.toString());
        data.put("refund_fee", refundFee.toString());
    	
        Map<String, String> resp;
		try {
			resp = wxpay.refund(data);
		} catch (Exception e) {
			log.error("",e);
			 throw new BizException("wxpay_refund_err", e.getMessage());
		}
        Map<String, Object> respMap=new HashMap<>();
        respMap.putAll(resp);
        return respMap;
		
	}
	
	/**
	 * 企业付款
	 */
	public Tips businessPayment(WXPayConfig config, String openid, double amount, String desc){
		Tips tips = new Tips("转账成功");
		Date date = DateUtils.getNowDate();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		String partnerTradeNo = sdf.format(date);
		int partnerTradeNoRandom = (int) (Math.random() * 1000);
		partnerTradeNo = partnerTradeNo + partnerTradeNoRandom;
 		String appId = config.getAppId();
		String mchId = config.getMchId();
		String key = config.getKey();
		String sign = "";
		String nonceStr = RandomUtil.getRandomStr();
		String checkName = "NO_CHECK";
		if(!StringUtils.hasText(desc)){
			desc = "企业付款" + amount + "元";
		}

		String spbill_create_ip = "223.73.196.252";
		Map<String, Object> signParams = new HashMap();
		signParams.put("mch_appid", appId);
		signParams.put("mchid", mchId);
		signParams.put("nonce_str", nonceStr);
		signParams.put("partner_trade_no", partnerTradeNo);
		signParams.put("openid", openid);
		signParams.put("check_name", checkName);
		signParams.put("amount", String.valueOf((int)(amount*100)));
		signParams.put("desc", desc);
		signParams.put("spbill_create_ip", spbill_create_ip);
		try {
			sign = wxApiSign.signPayMd5(signParams, key);
			signParams.put("sign", sign.toUpperCase());// 签名有了
			Map<String, String> wx = new HashMap();
			for (Entry<String, Object> e : signParams.entrySet()) {
				wx.put(e.getKey(), String.valueOf(e.getValue()));
			}
 			config.setKey(key);
			config.setMchId(mchId);
			String strUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
			WXPay wxPay = new WXPay(config);
			String resp = wxPay.requestWithCert(strUrl, wx, config.getHttpConnectTimeoutMs(),
					config.getHttpReadTimeoutMs());
			Map<String, String> map = WXPayUtil.xmlToMap(resp);
			String resultTime = "";
			String resultCode = "";
			SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			if (map.containsKey("payment_time")) {
				resultTime = map.get("payment_time");
			} else {
				resultTime = sdf1.format(new Date());
			}
			if ("SUCCESS".equals(map.get("result_code"))) {
				resultCode = map.get("result_code");
			} else {
				resultCode = "错误代码为：" + map.get("err_code") + "-----" + map.get("err_code_des");
				tips.setErrMsg(resultCode);
			}
		} catch (Exception e) {
			tips.setErrMsg(e.getMessage());
		}
		return tips;
	}
	/*
	 * 添加分账接收方
	 */
	@Override
	public Map<String, Object> profitsharingaddreceiver(String appid, String mchId,String key, String receiver) throws Exception{
		// TODO Auto-generated method stub
			Map<String,Object> m=new HashMap<String,Object>();
		    Map<String,String> p=new HashMap<>();
			String nonceStr=RandomUtil.getRandomStr();
			p.put("appid", appid);
			p.put("mch_id",mchId);
			p.put("nonce_str", nonceStr);
			p.put("receiver", receiver);
			p.put("sign_type", "HMAC-SHA256");
			String sign = wxApiSign.paySignDesposit(p,key); //生成签名
			p.put("sign", sign.toUpperCase());
			log.debug("发送给微信的接收方：appid："+appid+"新增接收方："+receiver+"付出："+p);
			MyWxPayConfig config = new MyWxPayConfig(appid,mchId,key); 
			String strUrl = "https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver";
			WXPay wxPay = new WXPay(config);
			String resp = wxPay.requestWithCert(strUrl, p, config.getHttpConnectTimeoutMs(),
					config.getHttpReadTimeoutMs());
			Map<String, String> orderMap = WXPayUtil.xmlToMap(resp);
			log.debug("微信返回的数据："+orderMap);
//			Map<String,Object> orderMap=swapTemplate.send("wxapi_pay_profitsharingaddreceiver", p); 
			  if(orderMap.containsKey("return_code") && orderMap.containsKey("result_code")){
			    	if("SUCCESS".equalsIgnoreCase((String) orderMap.get("result_code"))){
			    		
			    		m.put("mchId", (String) orderMap.get("mch_id"));
			    		m.put("nonceStr", (String) orderMap.get("nonce_str"));
			    		m.put("appid", (String) orderMap.get("appid"));
			    		m.put("receiver", (String) orderMap.get("receiver"));
			    		m.put("nonceStr", (String) orderMap.get("nonce_str"));
			    		m.put("sign", orderMap.get("sign"));
			    		m.put("resultCode", "SUCCESS");
			    	}else{
//			    		m.put("resultCode", "FAIL");
//			    		m.put("ERRORMESSAGE", (String) orderMap.get("err_code_des"));
			    		if("ORDER_NOT_READY".equals((String)orderMap.get("err_code"))) {
			    			m.put("resultCode", "FAIL");
				    		m.put("ERRORMESSAGE", (String) orderMap.get("err_code_des"));
				    		m.put("errCode", (String)orderMap.get("err_code"));
			    		}else {
			    			throw new BizException((String) orderMap.get("err_code"), (String) orderMap.get("err_code_des"));
			    		}
			    	}
			    }else{
			    	/**
			    	return_code><![CDATA[FAIL]]></return_code>
			    	<return_msg><![CDATA[body参数长度有误]]></return_msg>
			    	</xml>
			    	**/
			    	String errMsg= (String) orderMap.get("return_msg");
			    	m.put("resultCode", "FAIL");
		    		m.put("ERRORMESSAGE", errMsg);
		    		
			    	throw new BizException("WxPayServie105",errMsg==null?"向微信申请分账接收方出错":errMsg);
			    }
			
			return m; 
	}

	/*
	 * 微信分账
	 */
	@Override
	public Map<String, Object> multiprofitsharing(String mchId, String appid, String key, String transactionId,
			String outOrderNo, String receivers) throws Exception {
		// TODO Auto-generated method stub
		Map<String,Object> m=new HashMap<String,Object>();
	 	String nonceStr=RandomUtil.getRandomStr();
	    Map<String,String> p=new HashMap<String,String>(); 
		p.put("appid", appid);
		p.put("mch_id",mchId);
		p.put("nonce_str",nonceStr);
		p.put("sign_type", "HMAC-SHA256");
		p.put("transaction_id", transactionId);
		p.put("out_order_no", outOrderNo);
		p.put("receivers", receivers);
		//生成签名
		String sign = wxApiSign.paySignDesposit(p,key);
		p.put("sign", sign.toUpperCase());
		log.debug("发送给微信的接收方：appid："+appid+"接收方："+receivers+"付出："+p);
		MyWxPayConfig config = new MyWxPayConfig(appid,mchId,key); 
		String strUrl = "https://api.mch.weixin.qq.com/secapi/pay/multiprofitsharing";
		WXPay wxPay = new WXPay(config);
		String resp = wxPay.requestWithCert(strUrl, p, config.getHttpConnectTimeoutMs(),
				config.getHttpReadTimeoutMs());
		Map<String, String> orderMap = WXPayUtil.xmlToMap(resp);
		log.debug("微信返回的数据："+orderMap);
		  if(orderMap.containsKey("return_code") && orderMap.containsKey("result_code")){
		    	if("SUCCESS".equalsIgnoreCase((String) orderMap.get("result_code"))){ 
		    		m.put("mchId", (String) orderMap.get("mch_id"));
		    		m.put("nonceStr", (String) orderMap.get("nonce_str"));
		    		m.put("appid", (String) orderMap.get("appid"));
		    		m.put("orderId", (String) orderMap.get("order_id"));
		    		m.put("transactionId", (String) orderMap.get("transaction_id"));
		    		m.put("outOrderNo", (String) orderMap.get("out_order_no"));
		    		m.put("sign", orderMap.get("sign"));
		    		m.put("status", "SUCCESS");
		    	}else{
		    		m.put("status", "FAIL");
		    		throw new BizException((String) orderMap.get("err_code"), (String) orderMap.get("err_code_des"));
		    	}
		    }else{
		    	/**
		    	return_code><![CDATA[FAIL]]></return_code>
		    	<return_msg><![CDATA[body参数长度有误]]></return_msg>
		    	</xml>
		    	**/
		    	String errMsg= (String) orderMap.get("return_msg");
		    	m.put("status", "FAIL");
		    	throw new BizException("WxPayServie105",errMsg==null?"向微信申请分账接收方出错":errMsg);
		    }
		
		return m;
	}

}
